//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

import { get_head_info, list_git_filter, list_repo, remove_repo, list_remote as list_local_remote, list_repo_branch, get_project_id } from '@/api/local_repo';
import { makeAutoObservable, runInAction } from 'mobx';
import type { LocalRepoInfo, HeadInfo, LocalRepoRemoteInfo, LocalRepoBranchInfo } from "@/api/local_repo";
import { message } from 'antd';
import { exists as exists_path } from '@tauri-apps/api/fs';
import { check_git_env } from "@/api/git_wrap";
import type { GitEnvCheckResult } from "@/api/git_wrap";
import { report_error } from '@/api/client_cfg';
import { getGitFlowInfo, type GitFlowInfo } from '@/api/git_flow';

export interface LocalRepoExtInfo {
    id: string;
    repoInfo: LocalRepoInfo;
    headInfo: HeadInfo;
    filterList: string[];
    branchList: LocalRepoBranchInfo[];
    remoteList: LocalRepoRemoteInfo[];
    gitFlowInfo: GitFlowInfo;
    projectId: string; //关系项目ID
}

export default class LocalRepoStore {
    constructor() {
        makeAutoObservable(this);
    }
    private _checkResult: GitEnvCheckResult | null = null;


    get checkResult() {
        return this._checkResult;
    }

    private _repoExtList: LocalRepoExtInfo[] = [];

    get repoExtList() {
        return this._repoExtList;
    }

    async loadRepoList() {
        const repoIdSet = new Set<string>();
        const tmpList = [] as LocalRepoExtInfo[];
        try {
            const res = await list_repo();
            for (const repo of res) {
                try {
                    const exist = await exists_path(repo.path);
                    if (!exist) {
                        await remove_repo(repo.id);
                        continue;
                    }
                    repoIdSet.add(repo.id);
                    tmpList.push({
                        id: repo.id,
                        repoInfo: repo,
                        headInfo: {
                            commit_id: "",
                            branch_name: "",
                            tag_name: "",
                            detached: false,
                        },
                        branchList: [],
                        filterList: [],
                        remoteList: [],
                        gitFlowInfo: {},
                        projectId: "",
                    });
                } catch (e) {
                    console.log(e);
                    report_error({
                        err_data: `${e}`,
                    });
                }
            }
            runInAction(() => {
                this._repoExtList = tmpList;
            });
        } catch (e) {
            console.log(e);
            report_error({
                err_data: `${e}`,
            });
            message.error(`${e}`);
        }
        this.inInit = false;
        //补充其他信息
        try {
            for (const repo of tmpList) {
                const headInfo = await get_head_info(repo.repoInfo.path);
                const branchList = await list_repo_branch(repo.repoInfo.path);
                const filterList = await list_git_filter(repo.repoInfo.path);
                const remoteList = await list_local_remote(repo.repoInfo.path);
                const gitFlowInfo = await getGitFlowInfo(repo.repoInfo.path);
                const projectId = await get_project_id(repo.repoInfo.path);
                repo.headInfo = headInfo;
                repo.branchList = branchList;
                repo.filterList = filterList;
                repo.remoteList = remoteList;
                repo.gitFlowInfo = gitFlowInfo;
                repo.projectId = projectId;
            }
            runInAction(() => {
                this._repoExtList = tmpList;
            });
        } catch (e) {
            console.log(e);
            report_error({
                err_data: `${e}`,
            });
            message.error(`${e}`);
        }
    };

    async onUpdateRepo(repoId: string) {
        const tmpList = this._repoExtList.slice();
        const index = tmpList.findIndex(item => item.id == repoId);
        if (index == -1) {
            return;
        }
        try {
            const headInfo = await get_head_info(tmpList[index].repoInfo.path);
            const branchList = await list_repo_branch(tmpList[index].repoInfo.path);
            const filterList = await list_git_filter(tmpList[index].repoInfo.path);
            const gitFlowInfo = await getGitFlowInfo(tmpList[index].repoInfo.path);
            const projectId = await get_project_id(tmpList[index].repoInfo.path);
            tmpList[index].headInfo = headInfo;
            tmpList[index].branchList = branchList;
            tmpList[index].filterList = filterList;
            tmpList[index].gitFlowInfo = gitFlowInfo;
            tmpList[index].projectId = projectId;
            runInAction(() => {
                this._repoExtList = tmpList;
            });
        } catch (e) {
            console.log(e);
            report_error({
                err_data: `${e}`,
            });
        }
    }

    onUpdateRepoName(repoId: string, name: string) {
        const tmpList = this._repoExtList.slice();
        const index = tmpList.findIndex(item => item.id == repoId);
        if (index == -1) {
            return;
        }
        tmpList[index].repoInfo.name = name;
        runInAction(() => {
            this._repoExtList = tmpList;
        });
    }

    onUpdateRepoColor(repoId: string, color: string) {
        const tmpList = this._repoExtList.slice();
        const index = tmpList.findIndex(item => item.id == repoId);
        if (index == -1) {
            return;
        }
        tmpList[index].repoInfo.color = color;
        runInAction(() => {
            this._repoExtList = tmpList;
        });
    }

    async removeRepo(repoId: string) {
        await remove_repo(repoId);
        await this.loadRepoList();
    }

    async checkGitEnv() {
        const res = await check_git_env();
        runInAction(() => {
            this._checkResult = res;
        });
    }

    //初始化
    private _inInit = false;

    get inInit() {
        return this._inInit;
    }

    private set inInit(val: boolean) {
        runInAction(() => {
            this._inInit = val;
        });
    }

    async init() {
        try {
            this.inInit = true;
            if (this.checkResult == null) {
                await this.checkGitEnv();
            }
            await this.loadRepoList();
        } finally {
            this.inInit = false;
        }
    }
}
